home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / usenet / volume2 / nethack / part03 < prev    next >
Encoding:
Internet Message Format  |  1987-07-29  |  54.6 KB

  1. Path: uunet!seismo!rutgers!ucla-cs!zen!ucbvax!decvax!tektronix!tekgen!tekred!games-request
  2. From: games-request@tekred.TEK.COM
  3. Newsgroups: comp.sources.games
  4. Subject: v02i003:  nethack - display oriented dungeons & dragons, Part03/16
  5. Message-ID: <1445@tekred.TEK.COM>
  6. Date: 28 Jul 87 17:21:42 GMT
  7. Sender: billr@tekred.TEK.COM
  8. Lines: 2298
  9. Approved: billr@tekred.TEK.COM
  10.  
  11. Submitted by: mike@genat.UUCP (Mike Stephenson)
  12. Comp.sources.games: Volume 2, Issue 3
  13. Archive-name: nethack/Part03
  14.  
  15.  
  16. #! /bin/sh
  17. # This is a shell archive.  Remove anything before this line, then unpack
  18. # it by saving it into a file and typing "sh file".  To overwrite existing
  19. # files, type "sh file -c".  You can also feed this as standard input via
  20. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  21. # will see the following message at the end:
  22. #        "End of archive 3 (of 16)."
  23. # Contents:  hack.c wield.c zap.c
  24. # Wrapped by billr@tekred on Tue Jul 28 09:49:22 1987
  25. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  26. if test -f hack.c -a "${1}" != "-c" ; then 
  27.   echo shar: Will not over-write existing file \"hack.c\"
  28. else
  29. echo shar: Extracting \"hack.c\" \(24139 characters\)
  30. sed "s/^X//" >hack.c <<'END_OF_hack.c'
  31. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  32. X/* hack.c - version 1.0.3 */
  33. X
  34. X#include <stdio.h>
  35. X#include "hack.h"
  36. X#ifdef UNIX
  37. Xstatic    char    SCCS_Id[] = "@(#)hack.c    1.3\t87/07/14";
  38. X#endif
  39. Xextern char news0();
  40. Xextern char *nomovemsg;
  41. Xextern char *exclam();
  42. Xextern struct obj *addinv();
  43. Xextern boolean hmon();
  44. X
  45. X/* called on movement:
  46. X    1. when throwing ball+chain far away
  47. X    2. when teleporting
  48. X    3. when walking out of a lit room
  49. X */
  50. Xunsee() {
  51. X    register x,y;
  52. X    register struct rm *lev;
  53. X
  54. X/*
  55. X    if(u.udispl){
  56. X        u.udispl = 0;
  57. X        newsym(u.udisx, u.udisy);
  58. X    }
  59. X*/
  60. X#ifndef QUEST
  61. X    if(seehx){
  62. X        seehx = 0;
  63. X    } else
  64. X#endif
  65. X    for(x = u.ux-1; x < u.ux+2; x++)
  66. X      for(y = u.uy-1; y < u.uy+2; y++) {
  67. X        if(!isok(x, y)) continue;
  68. X        lev = &levl[x][y];
  69. X#ifdef DGK
  70. X        if(!lev->lit && lev->scrsym == symbol.room) {
  71. X#else
  72. X        if(!lev->lit && lev->scrsym == '.') {
  73. X#endif
  74. X            lev->scrsym =' ';
  75. X            lev->new = 1;
  76. X            on_scr(x,y);
  77. X        }
  78. X    }
  79. X}
  80. X
  81. X/* called:
  82. X    in apply.c:  seeoff(0) - when taking a picture of yourself
  83. X    in do.c:     seeoff(0) - blind after drinking potion
  84. X    in do.c:     seeoff(1) - go up or down the stairs
  85. X    in eat.c:    seeoff(0) - blind after eating rotten food
  86. X    in mhitu.c:  seeoff(0) - blinded by a yellow light
  87. X    in mon.c:    seeoff(1) - swallowed
  88. X    in potion.c: seeoff(0) - quaffing or sniffing a potion of blindness
  89. X    in spell.c:  seeoff(0) - due to a cursed spellbook
  90. X    in trap.c:   seeoff(1) - fall through trapdoor
  91. X    in wizard.c: seeoff(0) - hit by a cream pie.
  92. X */
  93. Xseeoff(mode)    /* 1 to redo @, 0 to leave them */
  94. X{    /* 1 means misc movement, 0 means blindness */
  95. X    register x,y;
  96. X    register struct rm *lev;
  97. X
  98. X    if(u.udispl && mode){
  99. X        u.udispl = 0;
  100. X        levl[u.udisx][u.udisy].scrsym = news0(u.udisx,u.udisy);
  101. X    }
  102. X#ifndef QUEST
  103. X    if(seehx) {
  104. X        seehx = 0;
  105. X    } else
  106. X#endif
  107. X    if(!mode) {
  108. X        for(x = u.ux-1; x < u.ux+2; x++)
  109. X            for(y = u.uy-1; y < u.uy+2; y++) {
  110. X                if(!isok(x, y)) continue;
  111. X                lev = &levl[x][y];
  112. X#ifdef DGK
  113. X                if(!lev->lit && lev->scrsym == symbol.room)
  114. X#else
  115. X                if(!lev->lit && lev->scrsym == '.')
  116. X#endif
  117. X                    lev->seen = 0;
  118. X            }
  119. X    }
  120. X}
  121. X
  122. Xstatic
  123. Xmoverock() {
  124. X    register xchar rx, ry;
  125. X    register struct obj *otmp;
  126. X    register struct trap *ttmp;
  127. X
  128. X    while(otmp = sobj_at(ENORMOUS_ROCK, u.ux+u.dx, u.uy+u.dy)) {
  129. X        rx = u.ux+2*u.dx;
  130. X        ry = u.uy+2*u.dy;
  131. X        nomul(0);
  132. X        if(isok(rx,ry) && !IS_ROCK(levl[rx][ry].typ) &&
  133. X            (levl[rx][ry].typ != DOOR || !(u.dx && u.dy)) &&
  134. X            !sobj_at(ENORMOUS_ROCK, rx, ry)) {
  135. X            if(m_at(rx,ry)) {
  136. X                pline("You hear a monster behind the rock.");
  137. X                pline("Perhaps that's why you cannot move it.");
  138. X                goto cannot_push;
  139. X            }
  140. X            if(ttmp = t_at(rx,ry))
  141. X                switch(ttmp->ttyp) {
  142. X                case PIT:
  143. X                pline("You push the rock into a pit!");
  144. X                deltrap(ttmp);
  145. X                delobj(otmp);
  146. X                pline("It completely fills the pit!");
  147. X                continue;
  148. X                case TELEP_TRAP:
  149. X                pline("You push the rock and suddenly it disappears!");
  150. X                delobj(otmp);
  151. X                continue;
  152. X                }
  153. X            if(levl[rx][ry].typ == POOL) {
  154. X                levl[rx][ry].typ = ROOM;
  155. X                mnewsym(rx,ry);
  156. X                prl(rx,ry);
  157. X                pline("You push the rock into the water.");
  158. X                pline("Now you can cross the water!");
  159. X                delobj(otmp);
  160. X                continue;
  161. X            }
  162. X            otmp->ox = rx;
  163. X            otmp->oy = ry;
  164. X            /* pobj(otmp); */
  165. X            if(cansee(rx,ry)) atl(rx,ry,otmp->olet);
  166. X            if(Invisible) newsym(u.ux+u.dx, u.uy+u.dy);
  167. X
  168. X            { static long lastmovetime;
  169. X            /* note: this var contains garbage initially and
  170. X               after a restore */
  171. X            if(moves > lastmovetime+2 || moves < lastmovetime)
  172. X            pline("With great effort you move the enormous rock.");
  173. X            lastmovetime = moves;
  174. X            }
  175. X        } else {
  176. X            pline("You try to move the enormous rock, but in vain.");
  177. X        cannot_push:
  178. X#ifdef KAA
  179. X            if (u.usym=='9') {
  180. X# ifdef DGKMOD
  181. X            if(!flags.pickup)
  182. X                pline("You easily can push it aside.");
  183. X            else
  184. X# endif
  185. X                pline("However, you easily can pick it up.");
  186. X            break;
  187. X            }
  188. X#endif
  189. X            if((!invent || inv_weight()+90 <= 0) &&
  190. X            (!u.dx || !u.dy || (IS_ROCK(levl[u.ux][u.uy+u.dy].typ)
  191. X                    && IS_ROCK(levl[u.ux+u.dx][u.uy].typ)))){
  192. X            pline("However, you can squeeze yourself into a small opening.");
  193. X            break;
  194. X            } else
  195. X            return (-1);
  196. X        }
  197. X    }
  198. X    return (0);
  199. X}
  200. X
  201. Xdomove()
  202. X{
  203. X    register struct monst *mtmp;
  204. X    register struct rm *tmpr,*ust;
  205. X    struct trap *trap;
  206. X    register struct obj *otmp;
  207. X
  208. X    u_wipe_engr(rnd(5));
  209. X
  210. X    if(inv_weight() > 0){
  211. X        pline("You collapse under your load.");
  212. X        nomul(0);
  213. X        return;
  214. X    }
  215. X    if(u.uswallow) {
  216. X        u.dx = u.dy = 0;
  217. X        u.ux = u.ustuck->mx;
  218. X        u.uy = u.ustuck->my;
  219. X    } else {
  220. X        if(Confusion) {
  221. X            do {
  222. X                confdir();
  223. X            } while(!isok(u.ux+u.dx, u.uy+u.dy) ||
  224. X                IS_ROCK(levl[u.ux+u.dx][u.uy+u.dy].typ));
  225. X        }
  226. X        if(!isok(u.ux+u.dx, u.uy+u.dy)){
  227. X            nomul(0);
  228. X            return;
  229. X        }
  230. X    }
  231. X
  232. X    ust = &levl[u.ux][u.uy];
  233. X    u.ux0 = u.ux;
  234. X    u.uy0 = u.uy;
  235. X    if(!u.uswallow && (trap = t_at(u.ux+u.dx, u.uy+u.dy)) && trap->tseen)
  236. X        nomul(0);
  237. X    if(u.ustuck && !u.uswallow && (u.ux+u.dx != u.ustuck->mx ||
  238. X        u.uy+u.dy != u.ustuck->my)) {
  239. X        if(dist(u.ustuck->mx, u.ustuck->my) > 2){
  240. X            /* perhaps it fled (or was teleported or ... ) */
  241. X            u.ustuck = 0;
  242. X        } else {
  243. X            if(Blind) pline("You cannot escape from it!");
  244. X            else pline("You cannot escape from %s!",
  245. X                monnam(u.ustuck));
  246. X            nomul(0);
  247. X            return;
  248. X        }
  249. X    }
  250. X    if(u.uswallow || (mtmp = m_at(u.ux+u.dx,u.uy+u.dy))) {
  251. X    /* attack monster */
  252. X
  253. X#ifdef SAFE_ATTACK
  254. X        /* Don't attack if you're running */
  255. X        if (flags.run && !mtmp->mimic
  256. X        && (Blind ? Telepat : (!mtmp->minvis || See_invisible))) {
  257. X            nomul(0);
  258. X            flags.move = 0;
  259. X            return;
  260. X        }
  261. X#endif
  262. X        nomul(0);
  263. X        gethungry();
  264. X        if(multi < 0) return;    /* we just fainted */
  265. X
  266. X        /* try to attack; note that it might evade */
  267. X        if(attack(u.uswallow ? u.ustuck : mtmp))
  268. X            return;
  269. X    }
  270. X    /* not attacking an animal, so we try to move */
  271. X    if(u.utrap) {
  272. X        if(u.utraptype == TT_PIT) {
  273. X            pline("You are still in a pit.");
  274. X            u.utrap--;
  275. X        } else {
  276. X            pline("You are caught in a beartrap.");
  277. X            if((u.dx && u.dy) || !rn2(5)) u.utrap--;
  278. X        }
  279. X        return;
  280. X    }
  281. X    tmpr = &levl[u.ux+u.dx][u.uy+u.dy];
  282. X    if(IS_ROCK(tmpr->typ) ||
  283. X       (u.dx && u.dy && (tmpr->typ == DOOR || ust->typ == DOOR))){
  284. X        flags.move = 0;
  285. X        nomul(0);
  286. X        return;
  287. X    }
  288. X    if(moverock() < 0) return;
  289. X    if(u.dx && u.dy && IS_ROCK(levl[u.ux][u.uy+u.dy].typ) &&
  290. X        IS_ROCK(levl[u.ux+u.dx][u.uy].typ) &&
  291. X        invent && inv_weight()+40 > 0) {
  292. X        pline("You are carrying too much to get through.");
  293. X        nomul(0);
  294. X        return;
  295. X    }
  296. X    if(Punished &&
  297. X       DIST(u.ux+u.dx, u.uy+u.dy, uchain->ox, uchain->oy) > 2){
  298. X        if(carried(uball)) {
  299. X            movobj(uchain, u.ux, u.uy);
  300. X            goto nodrag;
  301. X        }
  302. X
  303. X        if(DIST(u.ux+u.dx, u.uy+u.dy, uball->ox, uball->oy) < 3){
  304. X            /* leave ball, move chain under/over ball */
  305. X            movobj(uchain, uball->ox, uball->oy);
  306. X            goto nodrag;
  307. X        }
  308. X
  309. X        if(inv_weight() + (int) uball->owt/2 > 0) {
  310. X            pline("You cannot %sdrag the heavy iron ball.",
  311. X            invent ? "carry all that and also " : "");
  312. X            nomul(0);
  313. X            return;
  314. X        }
  315. X
  316. X        movobj(uball, uchain->ox, uchain->oy);
  317. X        unpobj(uball);        /* BAH %% */
  318. X        uchain->ox = u.ux;
  319. X        uchain->oy = u.uy;
  320. X        nomul(-2);
  321. X        nomovemsg = "";
  322. X    nodrag:    ;
  323. X    }
  324. X    u.ux += u.dx;
  325. X    u.uy += u.dy;
  326. X    if(flags.run) {
  327. X        if(tmpr->typ == DOOR ||
  328. X        (xupstair == u.ux && yupstair == u.uy) ||
  329. X        (xdnstair == u.ux && ydnstair == u.uy)
  330. X#ifdef FOUNTAINS
  331. X        || IS_FOUNTAIN(levl[u.ux][u.uy].typ)
  332. X#endif
  333. X#ifdef NEWCLASS
  334. X        || IS_THRONE(levl[u.ux][u.uy].typ)
  335. X#endif
  336. X        )
  337. X            nomul(0);
  338. X    }
  339. X
  340. X    if(tmpr->typ == POOL && !Levitation)
  341. X        drown();    /* not necessarily fatal */
  342. X
  343. X/*
  344. X    if(u.udispl) {
  345. X        u.udispl = 0;
  346. X        newsym(u.ux0,u.uy0);
  347. X    }
  348. X*/
  349. X    if(!Blind) {
  350. X#ifdef QUEST
  351. X        setsee();
  352. X#else
  353. X        if(ust->lit) {
  354. X            if(tmpr->lit) {
  355. X                if(tmpr->typ == DOOR)
  356. X                    prl1(u.ux+u.dx,u.uy+u.dy);
  357. X                else if(ust->typ == DOOR)
  358. X                    nose1(u.ux0-u.dx,u.uy0-u.dy);
  359. X            } else {
  360. X                unsee();
  361. X                prl1(u.ux+u.dx,u.uy+u.dy);
  362. X            }
  363. X        } else {
  364. X            if(tmpr->lit) setsee();
  365. X            else {
  366. X                prl1(u.ux+u.dx,u.uy+u.dy);
  367. X                if(tmpr->typ == DOOR) {
  368. X                    if(u.dy) {
  369. X                        prl(u.ux-1,u.uy);
  370. X                        prl(u.ux+1,u.uy);
  371. X                    } else {
  372. X                        prl(u.ux,u.uy-1);
  373. X                        prl(u.ux,u.uy+1);
  374. X                    }
  375. X                }
  376. X            }
  377. X            nose1(u.ux0-u.dx,u.uy0-u.dy);
  378. X        }
  379. X#endif /* QUEST /**/
  380. X    } else {
  381. X        pru();
  382. X    }
  383. X    if(!flags.nopick) pickup(1);
  384. X    if(trap) dotrap(trap);        /* fall into pit, arrow trap, etc. */
  385. X    (void) inshop();
  386. X    if(!Blind) read_engr_at(u.ux,u.uy);
  387. X}
  388. X
  389. Xmovobj(obj, ox, oy)
  390. Xregister struct obj *obj;
  391. Xregister int ox, oy;
  392. X{
  393. X    /* Some dirty programming to get display right */
  394. X    freeobj(obj);
  395. X    unpobj(obj);
  396. X    obj->nobj = fobj;
  397. X    fobj = obj;
  398. X    obj->ox = ox;
  399. X    obj->oy = oy;
  400. X}
  401. X
  402. Xdopickup(){
  403. X    /* uswallow case added by GAN 01/29/87 */
  404. X    if(u.uswallow)  {
  405. X        pline("You pick up %s's tongue.",monnam(u.ustuck));
  406. X        pline("But it's kind of slimy, so you drop it.");
  407. X        return(1);
  408. X    }
  409. X    if(!g_at(u.ux,u.uy) && !o_at(u.ux,u.uy)) {
  410. X        pline("There is nothing here to pick up.");
  411. X        return(0);
  412. X    }
  413. X    if(Levitation) {
  414. X        pline("You cannot reach the floor.");
  415. X        return(1);
  416. X    }
  417. X    pickup(0);
  418. X    return(1);
  419. X}
  420. X
  421. Xpickup(all)
  422. X{
  423. X    register struct gold *gold;
  424. X    register struct obj *obj, *obj2;
  425. X    register int wt;
  426. X    char buf[BUFSZ];
  427. X    register char *ip;
  428. X    register char sym;
  429. X    register int oletct = 0, iletct = 0;
  430. X    char olets[20], ilets[20];
  431. X
  432. X    if(Levitation) return;
  433. X#ifdef DGKMOD
  434. X    if (all && !flags.pickup) {
  435. X        int ct = 0;
  436. X
  437. X        for (obj = fobj; obj; obj = obj->nobj)
  438. X            if (obj->ox == u.ux && obj->oy == u.uy)
  439. X                if (!Punished || obj != uchain)
  440. X                    ct++;
  441. X        /* If gold is the only thing here, pick it up.
  442. X         */
  443. X        if (!ct && g_at(u.ux, u.uy)) {
  444. X            if (flags.run) nomul(0);
  445. X            while (gold = g_at(u.ux,u.uy)) {
  446. X                pline("%ld gold piece%s.", gold->amount,
  447. X                    plur(gold->amount));
  448. X                u.ugold += gold->amount;
  449. X                flags.botl = 1;
  450. X                freegold(gold);
  451. X            }
  452. X            if (Invisible) newsym(u.ux,u.uy);
  453. X        }
  454. X
  455. X        /* If there are objects here, take a look.
  456. X         */
  457. X        if (ct) {
  458. X            if (flags.run)
  459. X                nomul(0);
  460. X            nscr();
  461. X            if (ct < 5)
  462. X                dolook();
  463. X            else
  464. X                pline("There are several objects here.");
  465. X        }
  466. X        return;
  467. X    }
  468. X#endif
  469. X    while(gold = g_at(u.ux,u.uy)) {
  470. X        pline("%ld gold piece%s.", gold->amount, plur(gold->amount));
  471. X        u.ugold += gold->amount;
  472. X        flags.botl = 1;
  473. X        freegold(gold);
  474. X        if(flags.run) nomul(0);
  475. X        if(Invisible) newsym(u.ux,u.uy);
  476. X    }
  477. X    /* check for more than one object */
  478. X    if(!all) {
  479. X        register int ct = 0;
  480. X
  481. X        for(obj = fobj; obj; obj = obj->nobj)
  482. X            if(obj->ox == u.ux && obj->oy == u.uy) ct++;
  483. X        if(g_at(u.ux,u.uy))
  484. X            ct++;
  485. X        if(ct < 2)
  486. X            all++;
  487. X        else
  488. X            pline("There are several objects here.");
  489. X    }
  490. X
  491. X    /* added by GAN 10/24/86 to allow selective picking up */
  492. X    if(!all)  {
  493. X        register struct obj *otmp = fobj;
  494. X
  495. X        if(g_at(u.ux,u.uy)) ilets[iletct++] = '$';
  496. X        ilets[iletct] = 0;
  497. X        while(otmp) {
  498. X            if(!index(ilets, otmp->olet) &&
  499. X               otmp->ox == u.ux && otmp->oy == u.uy)  {
  500. X                ilets[iletct++] = otmp->olet;
  501. X                ilets[iletct] = 0;
  502. X            }
  503. X            otmp = otmp->nobj;
  504. X        }        
  505. X        if(iletct == 1)
  506. X            strcpy(buf,ilets);
  507. X        else  {
  508. X            ilets[iletct++] = ' ';
  509. X            ilets[iletct++] = 'a';
  510. X            ilets[iletct++] = 'A';
  511. X            ilets[iletct] = 0;
  512. X
  513. X            if(iletct = 3)    
  514. X            pline("What kinds of thing do you want to pick up? [%s]", ilets);
  515. X            getlin(buf);
  516. X            if(buf[0] == '\033') {
  517. X                clrlin();
  518. X                return(0);
  519. X            }
  520. X        }
  521. X        ip = buf;
  522. X        olets[0] = 0;
  523. X        while(sym = *ip++){
  524. X            /* new A function (selective all) added by
  525. X             * GAN 01/09/87
  526. X             */
  527. X            if(sym == 'A')  {
  528. X                for(oletct = 0; ilets[oletct] != ' '; oletct++)
  529. X                    olets[oletct] = ilets[oletct];
  530. X                olets[oletct] = 0;
  531. X                break;
  532. X            }
  533. X            if(sym == ' ') continue;
  534. X            if(sym == 'a') all++; else
  535. X            if(index(ilets, sym)){
  536. X                if(!index(olets, sym)){
  537. X                    olets[oletct++] = sym;
  538. X                    olets[oletct] = 0;
  539. X                }
  540. X            }
  541. X            else pline("There are no %c's here.", sym);
  542. X        }        
  543. X    }
  544. X
  545. X    if(all || index(olets,'$'))
  546. X        while(gold = g_at(u.ux,u.uy)) {
  547. X            pline("%ld gold piece%s.", gold->amount,
  548. X               plur(gold->amount));
  549. X            u.ugold += gold->amount;
  550. X            flags.botl = 1;
  551. X            freegold(gold);
  552. X            if(flags.run) nomul(0);
  553. X            if(Invis) newsym(u.ux,u.uy);
  554. X    }
  555. X
  556. X
  557. X    for(obj = fobj; obj; obj = obj2) {
  558. X        obj2 = obj->nobj;   /* perhaps obj will be picked up */
  559. X        if(obj->ox == u.ux && obj->oy == u.uy) {
  560. X        if(flags.run) nomul(0);
  561. X
  562. X        if(!all)  {
  563. X            char c;
  564. X               
  565. X            if(!index(olets,obj->olet)) continue;
  566. X            pline("Pick up %s ? [ynaq]", doname(obj));
  567. X            while(!index("ynaq ", (c = readchar())))
  568. X                bell();
  569. X            if(c == 'q') return;
  570. X            if(c == 'n') continue;
  571. X            if(c == 'a') all = 1;
  572. X        }
  573. X        if(obj->otyp == DEAD_COCKATRICE && !uarmg && u.usym != 'c') {
  574. X            pline("Touching the dead cockatrice is a fatal mistake.");
  575. X            pline("You turn to stone.");
  576. X            pline("You die...");
  577. X            killer = "cockatrice cadaver";
  578. X            done("died");
  579. X        }        
  580. X        if(obj->otyp == SCR_SCARE_MONSTER){
  581. X          if(!obj->spe) obj->spe = 1;
  582. X          else {
  583. X            /* Note: perhaps the 1st pickup failed: you cannot
  584. X            carry anymore, and so we never dropped it -
  585. X            lets assume that treading on it twice also
  586. X            destroys the scroll */
  587. X            pline("The scroll turns to dust as you pick it up.");
  588. X#ifdef KAA
  589. X            if(!(objects[SCR_SCARE_MONSTER].oc_name_known) &&
  590. X               !(objects[SCR_SCARE_MONSTER].oc_uname))
  591. X                docall(obj);
  592. X#endif
  593. X            delobj(obj);
  594. X            continue;
  595. X          }
  596. X        }
  597. X           
  598. X        /* do not pick up uchain */
  599. X        if(Punished && obj == uchain)
  600. X            continue;
  601. X
  602. X                  
  603. X        wt = inv_weight() + obj->owt;
  604. X        if(wt > 0) {
  605. X            if(obj->quan > 1) {
  606. X                /* see how many we can lift */
  607. X                extern struct obj *splitobj();
  608. X                int savequan = obj->quan;
  609. X                int iw = inv_weight();
  610. X                int qq;
  611. X                for(qq = 1; qq < savequan; qq++){
  612. X                    obj->quan = qq;
  613. X                    if(iw + weight(obj) > 0)
  614. X                        break;
  615. X                }
  616. X                obj->quan = savequan;
  617. X                qq--;
  618. X                /* we can carry qq of them */
  619. X                if(!qq) goto too_heavy;
  620. X            pline("You can only carry %s of the %s lying here.",
  621. X                    (qq == 1) ? "one" : "some",
  622. X                    doname(obj));
  623. X                (void) splitobj(obj, qq);
  624. X                /* note: obj2 is set already, so well never
  625. X                 * encounter the other half; if it should be
  626. X                 * otherwise then write
  627. X                 *      obj2 = splitobj(obj,qq);
  628. X                 */
  629. X                goto lift_some;
  630. X            }          
  631. X        too_heavy:
  632. X            pline("There %s %s here, but %s.",
  633. X                (obj->quan == 1) ? "is" : "are",
  634. X                doname(obj),
  635. X                !invent ? "it is too heavy for you to lift"
  636. X                /* There is no such word as "anymore". KAA */
  637. X                    : "you cannot carry any more");
  638. X            break;
  639. X        }
  640. X    lift_some:
  641. X        if(inv_cnt() >= 52) {
  642. X            pline("Your knapsack cannot accomodate any more items.");
  643. X            break;
  644. X        }
  645. X        if(wt > -5) pline("You have a little trouble lifting");
  646. X        freeobj(obj);
  647. X        if(Invisible) newsym(u.ux,u.uy);
  648. X        addtobill(obj);       /* sets obj->unpaid if necessary */
  649. X        { int pickquan = obj->quan;
  650. X          int mergquan;
  651. X#ifdef KAA
  652. X        if(!Blind) if(obj->olet != WEAPON_SYM) obj->dknown = 1;
  653. X#else
  654. X        if(!Blind) obj->dknown = 1;     /* this is done by prinv(),
  655. X                 but addinv() needs it already for merging */
  656. X#endif
  657. X        obj = addinv(obj);    /* might merge it with other objects */
  658. X          mergquan = obj->quan;
  659. X          obj->quan = pickquan; /* to fool prinv() */
  660. X        prinv(obj);
  661. X          obj->quan = mergquan;
  662. X        }
  663. X        }
  664. X    }
  665. X}
  666. X
  667. X/* stop running if we see something interesting */
  668. X/* turn around a corner if that is the only way we can proceed */
  669. X/* do not turn left or right twice */
  670. Xlookaround(){
  671. Xregister x,y,i,x0,y0,m0,i0 = 9;
  672. Xregister int corrct = 0, noturn = 0;
  673. Xregister struct monst *mtmp;
  674. X#ifdef lint
  675. X    /* suppress "used before set" message */
  676. X    x0 = y0 = 0;
  677. X#endif
  678. X    if(Blind || flags.run == 0) return;
  679. X    if(flags.run == 1 && levl[u.ux][u.uy].typ == ROOM) return;
  680. X#ifdef QUEST
  681. X    if(u.ux0 == u.ux+u.dx && u.uy0 == u.uy+u.dy) goto stop;
  682. X#endif
  683. X    for(x = u.ux-1; x <= u.ux+1; x++) for(y = u.uy-1; y <= u.uy+1; y++){
  684. X        if(x == u.ux && y == u.uy) continue;
  685. X        if(!levl[x][y].typ) continue;
  686. X        if((mtmp = m_at(x,y)) && !mtmp->mimic &&
  687. X            (!mtmp->minvis || See_invisible)){
  688. X            if(!mtmp->mtame || (x == u.ux+u.dx && y == u.uy+u.dy))
  689. X                goto stop;
  690. X        } else mtmp = 0; /* invisible M cannot influence us */
  691. X        if(x == u.ux-u.dx && y == u.uy-u.dy) continue;
  692. X#ifdef DGK
  693. X        {
  694. X        register uchar sym = levl[x][y].scrsym;
  695. X
  696. X        if (sym == symbol.vwall || sym == symbol.hwall
  697. X            || sym == symbol.room || sym == ' ' || IS_CORNER(sym))
  698. X            continue;
  699. X        else if (sym == symbol.door) {
  700. X            if(x != u.ux && y != u.uy) continue;
  701. X            if(flags.run != 1) goto stop;
  702. X            goto corr;
  703. X        } else if (sym == symbol.corr) {
  704. X        corr:
  705. X            if(flags.run == 1 || flags.run == 3) {
  706. X                i = DIST(x,y,u.ux+u.dx,u.uy+u.dy);
  707. X                if(i > 2) continue;
  708. X                if(corrct == 1 && DIST(x,y,x0,y0) != 1)
  709. X                    noturn = 1;
  710. X                if(i < i0) {
  711. X                    i0 = i;
  712. X                    x0 = x;
  713. X                    y0 = y;
  714. X                    m0 = mtmp ? 1 : 0;
  715. X                }
  716. X            }
  717. X            corrct++;
  718. X            continue;
  719. X        } else if (sym == '^') {
  720. X            if(flags.run == 1) goto corr;    /* if you must */
  721. X            if(x == u.ux+u.dx && y == u.uy+u.dy) goto stop;
  722. X            continue;
  723. X        } else {        /* e.g. objects or trap or stairs */
  724. X            if(flags.run == 1) goto corr;
  725. X            if(mtmp) continue;        /* d */
  726. X        }
  727. X        stop:
  728. X            nomul(0);
  729. X            return;
  730. X        }
  731. X#else
  732. X        switch(levl[x][y].scrsym){
  733. X        case '|':
  734. X        case '-':
  735. X        case '.':
  736. X        case ' ':
  737. X            break;
  738. X        case '+':
  739. X            if(x != u.ux && y != u.uy) break;
  740. X            if(flags.run != 1) goto stop;
  741. X            /* fall into next case */
  742. X        case CORR_SYM:
  743. X        corr:
  744. X            if(flags.run == 1 || flags.run == 3) {
  745. X                i = DIST(x,y,u.ux+u.dx,u.uy+u.dy);
  746. X                if(i > 2) break;
  747. X                if(corrct == 1 && DIST(x,y,x0,y0) != 1)
  748. X                    noturn = 1;
  749. X                if(i < i0) {
  750. X                    i0 = i;
  751. X                    x0 = x;
  752. X                    y0 = y;
  753. X                    m0 = mtmp ? 1 : 0;
  754. X                }
  755. X            }
  756. X            corrct++;
  757. X            break;
  758. X        case '^':
  759. X            if(flags.run == 1) goto corr;    /* if you must */
  760. X            if(x == u.ux+u.dx && y == u.uy+u.dy) goto stop;
  761. X            break;
  762. X        default:    /* e.g. objects or trap or stairs */
  763. X            if(flags.run == 1) goto corr;
  764. X            if(mtmp) break;        /* d */
  765. X        stop:
  766. X            nomul(0);
  767. X            return;
  768. X        }
  769. X#endif
  770. X    }
  771. X#ifdef QUEST
  772. X    if(corrct > 0 && (flags.run == 4 || flags.run == 5)) goto stop;
  773. X#endif
  774. X    if(corrct > 1 && flags.run == 2) goto stop;
  775. X    if((flags.run == 1 || flags.run == 3) && !noturn && !m0 && i0 &&
  776. X        (corrct == 1 || (corrct == 2 && i0 == 1))) {
  777. X        /* make sure that we do not turn too far */
  778. X        if(i0 == 2) {
  779. X            if(u.dx == y0-u.uy && u.dy == u.ux-x0)
  780. X            i = 2;        /* straight turn right */
  781. X            else
  782. X            i = -2;        /* straight turn left */
  783. X        } else if(u.dx && u.dy) {
  784. X            if((u.dx == u.dy && y0 == u.uy) ||
  785. X            (u.dx != u.dy && y0 != u.uy))
  786. X            i = -1;        /* half turn left */
  787. X            else
  788. X            i = 1;        /* half turn right */
  789. X        } else {
  790. X            if((x0-u.ux == y0-u.uy && !u.dy) ||
  791. X            (x0-u.ux != y0-u.uy && u.dy))
  792. X            i = 1;        /* half turn right */
  793. X            else
  794. X            i = -1;        /* half turn left */
  795. X        }
  796. X        i += u.last_str_turn;
  797. X        if(i <= 2 && i >= -2) {
  798. X            u.last_str_turn = i;
  799. X            u.dx = x0-u.ux, u.dy = y0-u.uy;
  800. X        }
  801. X    }
  802. X}
  803. X
  804. X/* something like lookaround, but we are not running */
  805. X/* react only to monsters that might hit us */
  806. Xmonster_nearby() {
  807. Xregister int x,y;
  808. Xregister struct monst *mtmp;
  809. X    if(!Blind)
  810. X    for(x = u.ux-1; x <= u.ux+1; x++) for(y = u.uy-1; y <= u.uy+1; y++){
  811. X        if(x == u.ux && y == u.uy) continue;
  812. X        if((mtmp = m_at(x,y)) && !mtmp->mimic && !mtmp->mtame &&
  813. X            !mtmp->mpeaceful && !index("Ea", mtmp->data->mlet) &&
  814. X            !mtmp->mfroz && !mtmp->msleep &&  /* aplvax!jcn */
  815. X            (!mtmp->minvis || See_invisible))
  816. X            return(1);
  817. X    }
  818. X    return(0);
  819. X}
  820. X
  821. X#ifdef QUEST
  822. Xcansee(x,y) xchar x,y; {
  823. Xregister int dx,dy,adx,ady,sdx,sdy,dmax,d;
  824. X    if(Blind) return(0);
  825. X    if(!isok(x,y)) return(0);
  826. X    d = dist(x,y);
  827. X    if(d < 3) return(1);
  828. X    if(d > u.uhorizon*u.uhorizon) return(0);
  829. X    if(!levl[x][y].lit)
  830. X        return(0);
  831. X    dx = x - u.ux;    adx = abs(dx);    sdx = sgn(dx);
  832. X    dy = y - u.uy;  ady = abs(dy);    sdy = sgn(dy);
  833. X    if(dx == 0 || dy == 0 || adx == ady){
  834. X        dmax = (dx == 0) ? ady : adx;
  835. X        for(d = 1; d <= dmax; d++)
  836. X            if(!rroom(sdx*d,sdy*d))
  837. X                return(0);
  838. X        return(1);
  839. X    } else if(ady > adx){
  840. X        for(d = 1; d <= ady; d++){
  841. X            if(!rroom(sdx*( (d*adx)/ady ), sdy*d) ||
  842. X               !rroom(sdx*( (d*adx-1)/ady+1 ), sdy*d))
  843. X                return(0);
  844. X        }
  845. X        return(1);
  846. X    } else {
  847. X        for(d = 1; d <= adx; d++){
  848. X            if(!rroom(sdx*d, sdy*( (d*ady)/adx )) ||
  849. X               !rroom(sdx*d, sdy*( (d*ady-1)/adx+1 )))
  850. X                return(0);
  851. X        }
  852. X        return(1);
  853. X    }
  854. X}
  855. X
  856. Xrroom(x,y) register int x,y; {
  857. X    return(IS_ROOM(levl[u.ux+x][u.uy+y].typ));
  858. X}
  859. X
  860. X#else
  861. X
  862. Xcansee(x,y) xchar x,y; {
  863. X    if(Blind || u.uswallow) return(0);
  864. X    if(dist(x,y) < 3) return(1);
  865. X    if(levl[x][y].lit && seelx <= x && x <= seehx && seely <= y &&
  866. X        y <= seehy) return(1);
  867. X    return(0);
  868. X}
  869. X#endif /* QUEST /**/
  870. X
  871. Xsgn(a) register int a; {
  872. X    return((a > 0) ? 1 : (a == 0) ? 0 : -1);
  873. X}
  874. X
  875. X#ifdef QUEST
  876. Xsetsee()
  877. X{
  878. X    register x,y;
  879. X
  880. X    if(Blind) {
  881. X        pru();
  882. X        return;
  883. X    }
  884. X    for(y = u.uy-u.uhorizon; y <= u.uy+u.uhorizon; y++)
  885. X        for(x = u.ux-u.uhorizon; x <= u.ux+u.uhorizon; x++) {
  886. X            if(cansee(x,y))
  887. X                prl(x,y);
  888. X    }
  889. X}
  890. X
  891. X#else
  892. X
  893. Xsetsee()
  894. X{
  895. X    register x,y;
  896. X
  897. X    if(Blind) {
  898. X        pru();
  899. X        return;
  900. X    }
  901. X    if(!levl[u.ux][u.uy].lit) {
  902. X        seelx = u.ux-1;
  903. X        seehx = u.ux+1;
  904. X        seely = u.uy-1;
  905. X        seehy = u.uy+1;
  906. X    } else {
  907. X        for(seelx = u.ux; levl[seelx-1][u.uy].lit; seelx--);
  908. X        for(seehx = u.ux; levl[seehx+1][u.uy].lit; seehx++);
  909. X        for(seely = u.uy; levl[u.ux][seely-1].lit; seely--);
  910. X        for(seehy = u.uy; levl[u.ux][seehy+1].lit; seehy++);
  911. X    }
  912. X    for(y = seely; y <= seehy; y++)
  913. X        for(x = seelx; x <= seehx; x++) {
  914. X            prl(x,y);
  915. X    }
  916. X    if(!levl[u.ux][u.uy].lit) seehx = 0; /* seems necessary elsewhere */
  917. X    else {
  918. X        if(seely == u.uy) for(x = u.ux-1; x <= u.ux+1; x++) prl(x,seely-1);
  919. X        if(seehy == u.uy) for(x = u.ux-1; x <= u.ux+1; x++) prl(x,seehy+1);
  920. X        if(seelx == u.ux) for(y = u.uy-1; y <= u.uy+1; y++) prl(seelx-1,y);
  921. X        if(seehx == u.ux) for(y = u.uy-1; y <= u.uy+1; y++) prl(seehx+1,y);
  922. X    }
  923. X}
  924. X#endif /* QUEST /**/
  925. X
  926. Xnomul(nval)
  927. Xregister nval;
  928. X{
  929. X#ifdef DGKMOD
  930. X    if(multi < nval) return;    /* This is a bug fix by ab@unido */
  931. X#else
  932. X    if(multi < 0) return;
  933. X#endif
  934. X    multi = nval;
  935. X    flags.mv = flags.run = 0;
  936. X}
  937. X
  938. Xabon()
  939. X{
  940. X#ifdef KAA
  941. X    if (u.usym != '@') return(mons[u.umonnum].mlevel-3);
  942. X#endif
  943. X    if(u.ustr == 3) return(-3);
  944. X    else if(u.ustr < 6) return(-2);
  945. X    else if(u.ustr < 8) return(-1);
  946. X    else if(u.ustr < 17) return(0);
  947. X    else if(u.ustr < 69) return(1);    /* up to 18/50 */
  948. X    else if(u.ustr < 118) return(2);
  949. X    else return(3);
  950. X}
  951. X
  952. Xdbon()
  953. X{
  954. X    if (u.usym != '@') return(0);
  955. X
  956. X    if(u.ustr < 6) return(-1);
  957. X    else if(u.ustr < 16) return(0);
  958. X    else if(u.ustr < 18) return(1);
  959. X    else if(u.ustr == 18) return(2);    /* up to 18 */
  960. X    else if(u.ustr < 94) return(3);        /* up to 18/75 */
  961. X    else if(u.ustr < 109) return(4);    /* up to 18/90 */
  962. X    else if(u.ustr < 118) return(5);    /* up to 18/99 */
  963. X    else return(6);
  964. X}
  965. X
  966. Xlosestr(num)    /* may kill you; cause may be poison or monster like 'A' */
  967. Xregister num;
  968. X{
  969. X    u.ustr -= num;
  970. X    while(u.ustr < 3) {
  971. X        u.ustr++;
  972. X        u.uhp -= 6;
  973. X        u.uhpmax -= 6;
  974. X    }
  975. X    flags.botl = 1;
  976. X}
  977. X
  978. Xlosehp(n,knam)
  979. Xregister n;
  980. Xregister char *knam;
  981. X{
  982. X#ifdef KAA
  983. X    if (u.mtimedone) {
  984. X        u.mh -= n;
  985. X        if (u.mhmax < u.mh) u.mhmax = u.mh;
  986. X        flags.botl = 1;
  987. X        if (u.mh < 1) rehumanize();
  988. X        return(0);
  989. X    }
  990. X#endif
  991. X    u.uhp -= n;
  992. X    if(u.uhp > u.uhpmax)
  993. X        u.uhpmax = u.uhp;    /* perhaps n was negative */
  994. X    flags.botl = 1;
  995. X    if(u.uhp < 1) {
  996. X        killer = knam;    /* the thing that killed you */
  997. X        pline("you died");
  998. X        done("died");
  999. X    }
  1000. X}
  1001. X
  1002. Xlosehp_m(n,mtmp)
  1003. Xregister n;
  1004. Xregister struct monst *mtmp;
  1005. X{
  1006. X#ifdef KAA
  1007. X    if (u.mtimedone) {
  1008. X        u.mh -= n;
  1009. X        flags.botl = 1;
  1010. X        if (u.mh < 1) rehumanize();
  1011. X        return;
  1012. X    }
  1013. X#endif
  1014. X    u.uhp -= n;
  1015. X    flags.botl = 1;
  1016. X    if(u.uhp < 1)
  1017. X        done_in_by(mtmp);
  1018. X}
  1019. X
  1020. Xlosexp()    /* hit by V or W */
  1021. X{
  1022. X    register num;
  1023. X    extern long newuexp();
  1024. X
  1025. X    if (u.usym == 'V' || u.usym=='W') return;
  1026. X
  1027. X    if(u.ulevel > 1)
  1028. X        pline("Goodbye level %u.", u.ulevel--);
  1029. X    else
  1030. X        u.uhp = -1;
  1031. X    num = rnd(10);
  1032. X    u.uhp -= num;
  1033. X    u.uhpmax -= num;
  1034. X#ifdef SPELLS
  1035. X    num = rnd(u.ulevel/2+1) + 1;        /* M. Stephenson */
  1036. X    u.uen -= num;
  1037. X    if (u.uen < 0)        u.uen = 0;
  1038. X    u.uenmax -= num;
  1039. X    if (u.uenmax < 0)    u.uenmax = 0;
  1040. X#endif
  1041. X    u.uexp = newuexp();
  1042. X    flags.botl = 1;
  1043. X}
  1044. X
  1045. Xinv_weight(){
  1046. Xregister struct obj *otmp = invent;
  1047. Xregister int wt = (u.ugold + 500)/1000;
  1048. Xregister int carrcap;
  1049. X#ifdef KAA
  1050. X    if (u.mtimedone) {
  1051. X        if (u.usym == '9') carrcap = MAX_CARR_CAP * 4;
  1052. X        else if (u.usym == 'N') carrcap = MAX_CARR_CAP;
  1053. X        else if (mons[u.umonnum].mlevel <= 3)
  1054. X            carrcap = 5*mons[u.umonnum].mlevel + 30;
  1055. X        else carrcap = 5*mons[u.umonnum].mlevel + 100;
  1056. X    }
  1057. X#endif
  1058. X    if(Levitation)            /* pugh@cornell */
  1059. X        carrcap = MAX_CARR_CAP;
  1060. X    else {
  1061. X        carrcap = 5*(((u.ustr > 18) ? 20 : u.ustr) + u.ulevel);
  1062. X        if(carrcap > MAX_CARR_CAP) carrcap = MAX_CARR_CAP;
  1063. X        if(Wounded_legs & LEFT_SIDE) carrcap -= 10;
  1064. X        if(Wounded_legs & RIGHT_SIDE) carrcap -= 10;
  1065. X    }
  1066. X    while(otmp){
  1067. X        wt += otmp->owt;
  1068. X        otmp = otmp->nobj;
  1069. X    }
  1070. X    return(wt - carrcap);
  1071. X}
  1072. X
  1073. Xinv_cnt(){
  1074. Xregister struct obj *otmp = invent;
  1075. Xregister int ct = 0;
  1076. X    while(otmp){
  1077. X        ct++;
  1078. X        otmp = otmp->nobj;
  1079. X    }
  1080. X    return(ct);
  1081. X}
  1082. X
  1083. Xlong
  1084. Xnewuexp()
  1085. X{
  1086. X    return(10*(1L << (u.ulevel-1)));
  1087. X}
  1088. END_OF_hack.c
  1089. if test 24139 -ne `wc -c <hack.c`; then
  1090.     echo shar: \"hack.c\" unpacked with wrong size!
  1091. fi
  1092. # end of overwriting check
  1093. fi
  1094. if test -f wield.c -a "${1}" != "-c" ; then 
  1095.   echo shar: Will not over-write existing file \"wield.c\"
  1096. else
  1097. echo shar: Extracting \"wield.c\" \(3307 characters\)
  1098. sed "s/^X//" >wield.c <<'END_OF_wield.c'
  1099. X/*    SCCS Id: @(#)wield.c    1.3    87/07/14
  1100. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  1101. X/* wield.c - version 1.0.3 */
  1102. X
  1103. X#include    "hack.h"
  1104. Xextern struct obj zeroobj;
  1105. Xextern char *hcolor();
  1106. X#ifdef KAA
  1107. Xextern boolean unweapon;
  1108. X#endif
  1109. X
  1110. Xsetuwep(obj) register struct obj *obj; {
  1111. X    setworn(obj, W_WEP);
  1112. X}
  1113. X
  1114. Xdowield()
  1115. X{
  1116. X    register struct obj *wep;
  1117. X    register int res = 0;
  1118. X
  1119. X    multi = 0;
  1120. X#ifdef KAA
  1121. X    if (cantwield(u.usym)) {
  1122. X        pline("Don't be ridiculous!");
  1123. X        return(0);
  1124. X    }
  1125. X#endif
  1126. X    if(!(wep = getobj("#-)", "wield"))) /* nothing */;
  1127. X    else if(uwep == wep)
  1128. X        pline("You are already wielding that!");
  1129. X    else if(welded(uwep))
  1130. X        pline("The %s welded to your hand!",
  1131. X            aobjnam(uwep, "are"));
  1132. X    else if(wep == &zeroobj) {
  1133. X        if(uwep == 0){
  1134. X            pline("You are already empty handed.");
  1135. X        } else {
  1136. X            setuwep((struct obj *) 0);
  1137. X            res++;
  1138. X            pline("You are empty handed.");
  1139. X        }
  1140. X    /* Prevent wielding a cockatrice in pack when not wearing gloves KAA*/
  1141. X    } else if (!uarmg && wep->otyp == DEAD_COCKATRICE) {
  1142. X        pline("You wield the dead cockatrice in your bare hands.");
  1143. X        pline("You turn to stone ...");
  1144. X        killer="dead cockatrice";
  1145. X        done("died");
  1146. X    } else if(uarms && wep->otyp == TWO_HANDED_SWORD)
  1147. X    pline("You cannot wield a two-handed sword and wear a shield.");
  1148. X    else if(wep->owornmask & (W_ARMOR | W_RING))
  1149. X        pline("You cannot wield that!");
  1150. X    else {
  1151. X        setuwep(wep);
  1152. X        res++;
  1153. X        if(welded(uwep))
  1154. X            pline("The %s %s to your hand!",
  1155. X            aobjnam(uwep, "weld"),
  1156. X            (uwep->quan == 1) ? "itself" : "themselves"); /* a3 */
  1157. X        else prinv(uwep);
  1158. X    }
  1159. X#ifdef KAA
  1160. X    if(res && uwep)
  1161. X        unweapon = (uwep->otyp >= BOW || uwep->otyp <= BOOMERANG) ? 
  1162. X        TRUE : FALSE;
  1163. X#endif
  1164. X    return(res);
  1165. X}
  1166. X
  1167. Xcorrode_weapon(){
  1168. X    if(!uwep || uwep->olet != WEAPON_SYM) return;    /* %% */
  1169. X    if(uwep->rustfree)
  1170. X        pline("Your %s not affected.", aobjnam(uwep, "are"));
  1171. X    else {
  1172. X        pline("Your %s!", aobjnam(uwep, "corrode"));
  1173. X        uwep->spe--;
  1174. X    }
  1175. X}
  1176. X
  1177. Xchwepon(otmp,amount)
  1178. Xregister struct obj *otmp;
  1179. Xregister amount;
  1180. X{
  1181. Xregister char *color = (amount < 0) ? "black" : "green";
  1182. Xregister char *time;
  1183. X
  1184. X    if(Hallucination) color=hcolor();
  1185. X    if(!uwep || uwep->olet != WEAPON_SYM) {
  1186. X        strange_feeling(otmp,
  1187. X            (amount > 0) ? "Your hands twitch."
  1188. X                     : "Your hands itch.");
  1189. X        return(0);
  1190. X    }
  1191. X
  1192. X    if(uwep->otyp == WORM_TOOTH && amount > 0) {
  1193. X        uwep->otyp = CRYSKNIFE;
  1194. X        pline("Your weapon seems sharper now.");
  1195. X        uwep->cursed = 0;
  1196. X        return(1);
  1197. X    }
  1198. X
  1199. X    if(uwep->otyp == CRYSKNIFE && amount < 0) {
  1200. X        uwep->otyp = WORM_TOOTH;
  1201. X        pline("Your weapon looks duller now.");
  1202. X        return(1);
  1203. X    }
  1204. X
  1205. X    /* there is a (soft) upper limit to uwep->spe */
  1206. X    if(amount > 0 && uwep->spe > 5 && rn2(3)) {
  1207. X        pline("Your %s violently %s for a while and then evaporate%s.",
  1208. X        aobjnam(uwep,"glow"),Hallucination ? hcolor() : "green",
  1209. X        plur(uwep->quan));
  1210. X
  1211. X        while(uwep)        /* let all of them disappear */
  1212. X                /* note: uwep->quan = 1 is nogood if unpaid */
  1213. X        useup(uwep);
  1214. X        return(1);
  1215. X    }
  1216. X    if(!rn2(6)) amount *= 2;
  1217. X    time = (amount*amount == 1) ? "moment" : "while";
  1218. X    pline("Your %s %s for a %s.",
  1219. X        aobjnam(uwep, "glow"), color, time);
  1220. X    uwep->spe += amount;
  1221. X    if(amount > 0) uwep->cursed = 0;
  1222. X    return(1);
  1223. X}
  1224. X
  1225. Xint
  1226. Xwelded(obj) register struct obj *obj;  {
  1227. X    return(obj == uwep && obj->cursed &&
  1228. X           (obj->olet == WEAPON_SYM || obj->otyp == HEAVY_IRON_BALL ||
  1229. X        obj->otyp == CAN_OPENER || obj->otyp == PICK_AXE));
  1230. X}
  1231. END_OF_wield.c
  1232. if test 3307 -ne `wc -c <wield.c`; then
  1233.     echo shar: \"wield.c\" unpacked with wrong size!
  1234. fi
  1235. # end of overwriting check
  1236. fi
  1237. if test -f zap.c -a "${1}" != "-c" ; then 
  1238.   echo shar: Will not over-write existing file \"zap.c\"
  1239. else
  1240. echo shar: Extracting \"zap.c\" \(23766 characters\)
  1241. sed "s/^X//" >zap.c <<'END_OF_zap.c'
  1242. X/*    SCCS Id: @(#)zap.c    1.3    87/07/14
  1243. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  1244. X/* zap.c - version 1.0.3 */
  1245. X
  1246. X#include "hack.h"
  1247. X
  1248. Xextern struct obj *mkobj_at();
  1249. Xextern struct monst *makemon(), *mkmon_at(), youmonst;
  1250. Xstruct monst *bhit();
  1251. Xchar *exclam();
  1252. X#ifdef KAA
  1253. Xextern char *xname();
  1254. X#endif
  1255. X
  1256. Xchar *fl[]= {
  1257. X    "magic missile",
  1258. X    "bolt of fire",
  1259. X    "sleep ray",
  1260. X    "bolt of cold",
  1261. X    "death ray",
  1262. X    "magic missle",        /* Spell equivalents of above wands */
  1263. X    "fireball",
  1264. X    "sleep ray",
  1265. X    "cone of cold",
  1266. X    "finger of death"
  1267. X};
  1268. X
  1269. X/* Routines for IMMEDIATE wands and spells. */
  1270. X/* bhitm: monster mtmp was hit by the effect of wand or spell otmp */
  1271. Xbhitm(mtmp, otmp)
  1272. Xregister struct monst *mtmp;
  1273. Xregister struct obj *otmp;
  1274. X{
  1275. X    wakeup(mtmp);
  1276. X    switch(otmp->otyp) {
  1277. X    case WAN_STRIKING:
  1278. X#ifdef SPELLS
  1279. X    case SPE_FORCE_BOLT:
  1280. X#endif
  1281. X        if(u.uswallow || rnd(20) < 10+mtmp->data->ac) {
  1282. X            register int tmp = d(2,12);
  1283. X            hit((otmp->otyp == WAN_STRIKING) ? "wand" : "spell", mtmp, exclam(tmp));
  1284. X            resist(mtmp, otmp->olet, tmp, TELL);
  1285. X        } else miss((otmp->otyp == WAN_STRIKING) ? "wand" : "spell", mtmp);
  1286. X        break;
  1287. X    case WAN_SLOW_MONSTER:
  1288. X#ifdef SPELLS
  1289. X    case SPE_SLOW_MONSTER:
  1290. X#endif
  1291. X        if(! resist(mtmp, otmp->olet, 0, NOTELL))
  1292. X            mtmp->mspeed = MSLOW;
  1293. X        break;
  1294. X    case WAN_SPEED_MONSTER:
  1295. X        if (!resist(mtmp, otmp->olet, 0, NOTELL))
  1296. X            mtmp->mspeed = MFAST;
  1297. X        break;
  1298. X    case WAN_UNDEAD_TURNING:
  1299. X#ifdef SPELLS
  1300. X    case SPE_TURN_UNDEAD:
  1301. X#endif
  1302. X        if(index(UNDEAD,mtmp->data->mlet)) {
  1303. X
  1304. X            if(!resist(mtmp, otmp->olet, rnd(8), NOTELL))
  1305. X                mtmp->mflee = 1;
  1306. X        }
  1307. X        break;
  1308. X    case WAN_POLYMORPH:
  1309. X#ifdef SPELLS
  1310. X    case SPE_POLYMORPH:
  1311. X#endif
  1312. X        if(!resist(mtmp, otmp->olet, 0, NOTELL))
  1313. X            if( newcham(mtmp,&mons[rn2(CMNUM)]) )
  1314. X            if (!Hallucination)
  1315. X                objects[otmp->otyp].oc_name_known = 1;
  1316. X        break;
  1317. X    case WAN_CANCELLATION:
  1318. X#ifdef SPELLS
  1319. X    case SPE_CANCELLATION:
  1320. X#endif
  1321. X        if(!resist(mtmp, otmp->olet, 0, NOTELL))
  1322. X            mtmp->mcan = 1;
  1323. X        break;
  1324. X    case WAN_TELEPORTATION:
  1325. X#ifdef SPELLS
  1326. X    case SPE_TELEPORT_AWAY:
  1327. X#endif
  1328. X        rloc(mtmp);
  1329. X        break;
  1330. X    case WAN_MAKE_INVISIBLE:
  1331. X        mtmp->minvis = 1;
  1332. X        break;
  1333. X    case WAN_NOTHING:
  1334. X        break;
  1335. X    case WAN_PROBING:
  1336. X#ifdef PROBING
  1337. X        mstatusline(mtmp);
  1338. X#else
  1339. X        pline("Nothing Happens.");
  1340. X#endif
  1341. X        break;
  1342. X    default:
  1343. X        impossible("What an interesting effect (%u)", otmp->otyp);
  1344. X    }
  1345. X}
  1346. X
  1347. Xbhito(obj, otmp)    /* object obj was hit by the effect of wand otmp */
  1348. Xregister struct obj *obj, *otmp;    /* returns TRUE if sth was done */
  1349. X{
  1350. X    register int res = TRUE;
  1351. X#ifdef DGKMOD
  1352. X    struct obj *otmp2;
  1353. X#endif
  1354. X
  1355. X    if(obj == uball || obj == uchain)
  1356. X        res = FALSE;
  1357. X    else
  1358. X    switch(otmp->otyp) {
  1359. X    case WAN_POLYMORPH:
  1360. X#ifdef SPELLS
  1361. X    case SPE_POLYMORPH:
  1362. X#endif
  1363. X        /* preserve symbol and quantity, but turn rocks into gems */
  1364. X#ifdef DGKMOD
  1365. X        otmp2 = mkobj_at((obj->otyp == ROCK
  1366. X            || obj->otyp == ENORMOUS_ROCK) ? GEM_SYM : obj->olet,
  1367. X            obj->ox, obj->oy);
  1368. X        otmp2->quan = obj->quan;
  1369. X        /* keep special fields (including charges on wands) */
  1370. X        /* The DGK modification doesn't allow polymorphing a weapon
  1371. X           with enchantments into another one, and doesn't allow 
  1372. X           polymorphed rings to have plusses.  KAA*/
  1373. X        if (index("/)[", otmp2->olet)) otmp2->spe = obj->spe;
  1374. X        otmp2->cursed = otmp->cursed;
  1375. X        /* update the weight */
  1376. X        otmp2->owt = weight(otmp2);
  1377. X#else
  1378. X        mkobj_at((obj->otyp == ROCK || obj->otyp == ENORMOUS_ROCK)
  1379. X            ? GEM_SYM : obj->olet,
  1380. X            obj->ox, obj->oy) -> quan = obj->quan;
  1381. X#endif
  1382. X        delobj(obj);
  1383. X        break;
  1384. X    case WAN_STRIKING:
  1385. X#ifdef SPELLS
  1386. X    case SPE_FORCE_BOLT:
  1387. X#endif
  1388. X        if(obj->otyp == ENORMOUS_ROCK)
  1389. X            fracture_rock(obj);
  1390. X        else
  1391. X            res = FALSE;
  1392. X        break;
  1393. X    case WAN_CANCELLATION:
  1394. X#ifdef SPELLS
  1395. X    case SPE_CANCELLATION:
  1396. X#endif
  1397. X        if(obj->spe && obj->olet != AMULET_SYM) {
  1398. X            obj->known = 0;
  1399. X            obj->spe = 0;
  1400. X        }
  1401. X        break;
  1402. X    case WAN_TELEPORTATION:
  1403. X#ifdef SPELLS
  1404. X    case SPE_TELEPORT_AWAY:
  1405. X#endif
  1406. X        rloco(obj);
  1407. X        break;
  1408. X    case WAN_MAKE_INVISIBLE:
  1409. X        obj->oinvis = 1;
  1410. X        break;
  1411. X    case WAN_UNDEAD_TURNING:
  1412. X#ifdef SPELLS
  1413. X    case SPE_TURN_UNDEAD:
  1414. X#endif
  1415. X        res = revive(obj);
  1416. X        break;
  1417. X    case WAN_SLOW_MONSTER:        /* no effect on objects */
  1418. X#ifdef SPELLS
  1419. X    case SPE_SLOW_MONSTER:
  1420. X#endif
  1421. X    case WAN_SPEED_MONSTER:
  1422. X    case WAN_NOTHING:
  1423. X    case WAN_PROBING:
  1424. X        res = FALSE;
  1425. X        break;
  1426. X    default:
  1427. X        impossible("What an interesting effect (%u)", otmp->otyp);
  1428. X    }
  1429. X    return(res);
  1430. X}
  1431. X
  1432. X/*
  1433. X * zappable - returns 1 if zap is available, 0 otherwise.
  1434. X *          it removes a charge from the wand if zappable.
  1435. X * added by GAN 11/03/86
  1436. X */
  1437. Xint
  1438. Xzappable(wand)
  1439. Xregister struct obj *wand;
  1440. X{
  1441. X    if(wand->spe < 0 || (wand->spe ==0 && rn2(121)))
  1442. X        return(0);
  1443. X    else  {
  1444. X        if(wand->spe == 0)
  1445. X            pline("You wrest one more spell from the worn-out wand.");
  1446. X        wand->spe--;
  1447. X        return(1);
  1448. X    }
  1449. X}
  1450. X
  1451. X/*
  1452. X * zapnodir - zaps an NODIR wand.
  1453. X * added by GAN 11/03/86
  1454. X */
  1455. Xzapnodir(wand)
  1456. Xregister struct obj *wand;
  1457. X{
  1458. X    switch(wand->otyp){
  1459. X        case WAN_LIGHT:
  1460. X            litroom(TRUE);
  1461. X            break;
  1462. X        case WAN_SECRET_DOOR_DETECTION:
  1463. X            if(!findit()) return(1);
  1464. X            break;
  1465. X        case WAN_CREATE_MONSTER:
  1466. X            { register int cnt = 1;
  1467. X            if(!rn2(23)) cnt += rn2(7) + 1;
  1468. X            while(cnt--)
  1469. X                (void) makemon((struct permonst *) 0, u.ux, u.uy);
  1470. X            }
  1471. X            break;
  1472. X        case WAN_WISHING:
  1473. X              
  1474. X            if(u.uluck + rn2(5) < 0) {
  1475. X                pline("Unfortunately, nothing happens.");
  1476. X                break;
  1477. X            }
  1478. X            makewish();
  1479. X            break;
  1480. X    }
  1481. X    if(!objects[wand->otyp].oc_name_known) {
  1482. X            objects[wand->otyp].oc_name_known = 1;
  1483. X            more_experienced(0,10);
  1484. X    }
  1485. X}
  1486. X
  1487. Xdozap()
  1488. X{
  1489. X    register struct obj *obj;
  1490. X    int    damage;
  1491. X
  1492. X    obj = getobj("/", "zap");
  1493. X    if(!obj) return(0);
  1494. X    
  1495. X    /* zappable addition done by GAN 11/03/86 */
  1496. X    if(!zappable(obj))  {
  1497. X        pline("Nothing Happens.");
  1498. X        return(1);
  1499. X    }
  1500. X    if(!(objects[obj->otyp].bits & NODIR) && !getdir(1)) {
  1501. X        pline("The %s glows and fades.",xname(obj));
  1502. X        return(1);    /* make him pay for knowing !NODIR */
  1503. X    }
  1504. X#ifdef KAA
  1505. X     if(!u.dx && !u.dy && !u.dz && !(objects[obj->otyp].bits & NODIR)) {
  1506. X
  1507. X        if((damage = zapyourself(obj)))
  1508. X            losehp(damage,"self-inflicted injury");
  1509. X        return(1);
  1510. X     }
  1511. X#endif
  1512. X    weffects(obj);
  1513. X    return(1);
  1514. X}
  1515. X
  1516. X#ifdef KAA
  1517. X#define    makeknown(x)    objects[x].oc_name_known = 1
  1518. X
  1519. Xzapyourself(obj)
  1520. X    register struct obj    *obj;
  1521. X{
  1522. Xstruct obj    *otmp;
  1523. Xint    damage = 0;
  1524. X
  1525. X      switch(obj->otyp) {
  1526. X           case WAN_STRIKING:
  1527. X            damage=d(8,6);
  1528. X            pline("The wand hits you!");
  1529. X            break;
  1530. X           case WAN_FIRE:
  1531. X            if (!Fire_resistance) damage=d(12,6);
  1532. X            pline("The wand sprays you with flames!");
  1533. X            makeknown(WAN_FIRE);
  1534. X            burn_scrolls();
  1535. X            boil_potions();
  1536. X            break;
  1537. X           case WAN_COLD:
  1538. X            if (!Cold_resistance) damage=d(12,6);
  1539. X            pline("You are blasted with liquid nitrogen!");
  1540. X            makeknown(WAN_COLD);
  1541. X            break;
  1542. X           case WAN_MAGIC_MISSILE:
  1543. X            damage = d(4,6);
  1544. X            pline("You are shot at point blank range!");
  1545. X            makeknown(WAN_MAGIC_MISSILE);
  1546. X            break;
  1547. X           case WAN_POLYMORPH:
  1548. X            makeknown(WAN_POLYMORPH);
  1549. X            polyself();
  1550. X            break;
  1551. X           case WAN_CANCELLATION:
  1552. X            for(otmp = invent; otmp; otmp = otmp->nobj)
  1553. X               if(otmp != uball && otmp->otyp != AMULET_OF_YENDOR)
  1554. X                  otmp->spe = 0;
  1555. X            if(u.mtimedone) rehumanize();
  1556. X            flags.botl = 1;  /* because of potential AC change */
  1557. X            find_ac();
  1558. X            break;
  1559. X           case WAN_MAKE_INVISIBLE:
  1560. X            HInvis |= INTRINSIC;
  1561. X            /* Tough luck if you cannot see invisible! */
  1562. X            if (!See_invisible) newsym(u.ux, u.uy);
  1563. X            break;
  1564. X           case WAN_SPEED_MONSTER:
  1565. X            Fast |= INTRINSIC;
  1566. X            break;
  1567. X           case WAN_SLEEP:
  1568. X            makeknown(WAN_SLEEP);
  1569. X            pline("The sleep ray hits you!");
  1570. X            nomul(-rn2(50));
  1571. X            break;
  1572. X           case WAN_SLOW_MONSTER:
  1573. X            Fast = 0;
  1574. X            break;
  1575. X           case WAN_TELEPORTATION:
  1576. X            tele();
  1577. X            break;
  1578. X           case WAN_DEATH:
  1579. X            pline("You irradiate yourself with pure energy!");
  1580. X            pline("You die.");
  1581. X            killer = "wand of death";
  1582. X            done("died");
  1583. X            break;
  1584. X           case WAN_DIGGING:
  1585. X           case WAN_UNDEAD_TURNING:
  1586. X           case WAN_NOTHING:
  1587. X            break;
  1588. X           default: impossible("object %d zap?",obj->otyp);
  1589. X      }
  1590. X    return(damage);
  1591. X}
  1592. X#endif /* KAA /**/
  1593. X
  1594. X/* called for various wand and spell effects - M. Stephenson */
  1595. Xweffects(obj)
  1596. X    register struct    obj    *obj;
  1597. X{
  1598. X    xchar zx,zy;
  1599. X
  1600. X    if(objects[obj->otyp].bits & IMMEDIATE) {
  1601. X        if(u.uswallow)
  1602. X            bhitm(u.ustuck, obj);
  1603. X        else if(u.dz) {
  1604. X            if(u.dz > 0 && o_at(u.ux,u.uy)) {
  1605. X                register struct obj *otmp;
  1606. X                
  1607. X                /* changed by GAN to hit all objects there */
  1608. X                for(otmp = fobj; otmp ; otmp = otmp->nobj)
  1609. X                    if(otmp->ox == u.ux &&
  1610. X                       otmp->oy == u.uy)
  1611. X                        (void) bhito(otmp, obj);
  1612. X            }
  1613. X        } else
  1614. X            (void) bhit(u.dx,u.dy,rn1(8,6),0,bhitm,bhito,obj);
  1615. X    } else {
  1616. X        switch(obj->otyp){
  1617. X        case WAN_LIGHT:
  1618. X#ifdef SPELLS
  1619. X        case SPE_LIGHT:
  1620. X#endif
  1621. X            litroom(TRUE);
  1622. X            break;
  1623. X        case WAN_SECRET_DOOR_DETECTION:
  1624. X#ifdef SPELLS
  1625. X        case SPE_DETECT_UNSEEN:
  1626. X#endif
  1627. X            if(!findit()) return(1);
  1628. X            break;
  1629. X        case WAN_CREATE_MONSTER:
  1630. X            { register int cnt = 1;
  1631. X            if(!rn2(23)) cnt += rn2(7) + 1;
  1632. X            while(cnt--)
  1633. X                (void) makemon((struct permonst *) 0, u.ux, u.uy);
  1634. X            }
  1635. X            break;
  1636. X        case WAN_WISHING:
  1637. X            if(u.uluck + rn2(5) < 0) {
  1638. X                pline("Unfortunately, nothing happens.");
  1639. X                break;
  1640. X            }
  1641. X            makewish();
  1642. X            break;
  1643. X        case WAN_DIGGING:
  1644. X#ifdef SPELLS
  1645. X        case SPE_DIG:
  1646. X#endif
  1647. X            /* Original effect (approximately):
  1648. X             * from CORR: dig until we pierce a wall
  1649. X             * from ROOM: piece wall and dig until we reach
  1650. X             * an ACCESSIBLE place.
  1651. X             * Currently: dig for digdepth positions;
  1652. X             * also down on request of Lennart Augustsson.
  1653. X             */
  1654. X            { register struct rm *room;
  1655. X              register int digdepth;
  1656. X            if(u.uswallow) {
  1657. X                register struct monst *mtmp = u.ustuck;
  1658. X
  1659. X                pline("You pierce %s's stomach wall!",
  1660. X                    monnam(mtmp));
  1661. X                mtmp->mhp = 1;    /* almost dead */
  1662. X                unstuck(mtmp);
  1663. X                mnexto(mtmp);
  1664. X                break;
  1665. X            }
  1666. X            if(u.dz) {
  1667. X                if(u.dz < 0) {
  1668. X                pline("You loosen a rock from the ceiling.");
  1669. X                pline("It falls on your head!");
  1670. X                losehp(1, "falling rock");
  1671. X                mksobj_at(ROCK, u.ux, u.uy);
  1672. X                fobj->quan = 1;
  1673. X                stackobj(fobj);
  1674. X                if(Invisible) newsym(u.ux, u.uy);
  1675. X                } else {
  1676. X                dighole();
  1677. X                }
  1678. X                break;
  1679. X            }
  1680. X            zx = u.ux+u.dx;
  1681. X            zy = u.uy+u.dy;
  1682. X            digdepth = 8 + rn2(18);
  1683. X            Tmp_at(-1, '*');    /* open call */
  1684. X            while(--digdepth >= 0) {
  1685. X                if(!isok(zx,zy)) break;
  1686. X                room = &levl[zx][zy];
  1687. X                Tmp_at(zx,zy);
  1688. X                if(!xdnstair){
  1689. X                    if(zx < 3 || zx > COLNO-3 ||
  1690. X                        zy < 3 || zy > ROWNO-3)
  1691. X                        break;
  1692. X                    if(room->typ == HWALL ||
  1693. X                        room->typ == VWALL){
  1694. X                        room->typ = ROOM;
  1695. X                        break;
  1696. X                    }
  1697. X                } else
  1698. X                if(room->typ == HWALL || room->typ == VWALL ||
  1699. X                   room->typ == SDOOR || room->typ == LDOOR){
  1700. X                    room->typ = DOOR;
  1701. X                    digdepth -= 2;
  1702. X                } else
  1703. X                if(room->typ == SCORR || !room->typ) {
  1704. X                    room->typ = CORR;
  1705. X                    digdepth--;
  1706. X                }
  1707. X                mnewsym(zx,zy);
  1708. X                zx += u.dx;
  1709. X                zy += u.dy;
  1710. X            }
  1711. X            mnewsym(zx,zy);    /* not always necessary */
  1712. X            Tmp_at(-1,-1);    /* closing call */
  1713. X            break;
  1714. X            }
  1715. X        default:
  1716. X#ifdef SPELLS
  1717. X            if((int) obj->otyp >= SPE_MAGIC_MISSILE) {
  1718. X
  1719. X                buzz((int) obj->otyp - SPE_MAGIC_MISSILE + 5,
  1720. X                    u.ux, u.uy, u.dx, u.dy);
  1721. X            } else
  1722. X#endif
  1723. X
  1724. X                buzz((int) obj->otyp - WAN_MAGIC_MISSILE,
  1725. X                    u.ux, u.uy, u.dx, u.dy);
  1726. X            break;
  1727. X        }
  1728. X        if(!objects[obj->otyp].oc_name_known) {
  1729. X            objects[obj->otyp].oc_name_known = 1;
  1730. X            more_experienced(0,10);
  1731. X        }
  1732. X    }
  1733. X    return;
  1734. X}
  1735. X
  1736. Xchar *
  1737. Xexclam(force)
  1738. Xregister int force;
  1739. X{
  1740. X    /* force == 0 occurs e.g. with sleep ray */
  1741. X    /* note that large force is usual with wands so that !! would
  1742. X        require information about hand/weapon/wand */
  1743. X    return( (force < 0) ? "?" : (force <= 4) ? "." : "!" );
  1744. X}
  1745. X
  1746. Xhit(str,mtmp,force)
  1747. Xregister char *str;
  1748. Xregister struct monst *mtmp;
  1749. Xregister char *force;        /* usually either "." or "!" */
  1750. X{
  1751. X    if(!cansee(mtmp->mx,mtmp->my)) pline("The %s hits it.", str);
  1752. X    else pline("The %s hits %s%s", str, monnam(mtmp), force);
  1753. X}
  1754. X
  1755. Xmiss(str,mtmp)
  1756. Xregister char *str;
  1757. Xregister struct monst *mtmp;
  1758. X{
  1759. X    if(!cansee(mtmp->mx,mtmp->my)) pline("The %s misses it.",str);
  1760. X    else pline("The %s misses %s.",str,monnam(mtmp));
  1761. X}
  1762. X
  1763. X/* bhit: called when a weapon is thrown (sym = obj->olet) or when an
  1764. X   IMMEDIATE wand is zapped (sym = 0); the weapon falls down at end of
  1765. X   range or when a monster is hit; the monster is returned, and bhitpos
  1766. X   is set to the final position of the weapon thrown; the ray of a wand
  1767. X   may affect several objects and monsters on its path - for each of
  1768. X   these an argument function is called. */
  1769. X/* check !u.uswallow before calling bhit() */
  1770. X
  1771. Xstruct monst *
  1772. Xbhit(ddx,ddy,range,sym,fhitm,fhito,obj)
  1773. Xregister int ddx,ddy,range;        /* direction and range */
  1774. Xchar sym;                /* symbol displayed on path */
  1775. Xint (*fhitm)(), (*fhito)();        /* fns called when mon/obj hit */
  1776. Xstruct obj *obj;            /* 2nd arg to fhitm/fhito */
  1777. X{
  1778. X    register struct monst *mtmp;
  1779. X    register struct obj *otmp;
  1780. X    register int typ;
  1781. X
  1782. X    bhitpos.x = u.ux;
  1783. X    bhitpos.y = u.uy;
  1784. X
  1785. X    if(sym) tmp_at(-1, sym);    /* open call */
  1786. X    while(range-- > 0) {
  1787. X        bhitpos.x += ddx;
  1788. X        bhitpos.y += ddy;
  1789. X        typ = levl[bhitpos.x][bhitpos.y].typ;
  1790. X        if(mtmp = m_at(bhitpos.x,bhitpos.y)){
  1791. X            if(sym) {
  1792. X                tmp_at(-1, -1);    /* close call */
  1793. X                return(mtmp);
  1794. X            }
  1795. X            (*fhitm)(mtmp, obj);
  1796. X            range -= 3;
  1797. X        }
  1798. X        /* modified by GAN to hit all objects */
  1799. X        if(fhito && o_at(bhitpos.x,bhitpos.y)){
  1800. X            int hitanything = 0;
  1801. X            for(otmp = fobj; otmp; otmp = otmp->nobj)
  1802. X                if(otmp->ox == bhitpos.x &&
  1803. X                   otmp->oy == bhitpos.y)
  1804. X                    hitanything += (*fhito)(otmp, obj);
  1805. X            if(hitanything)    range--;
  1806. X        }
  1807. X        if(!ZAP_POS(typ)) {
  1808. X            bhitpos.x -= ddx;
  1809. X            bhitpos.y -= ddy;
  1810. X            break;
  1811. X        }
  1812. X        if(sym) tmp_at(bhitpos.x, bhitpos.y);
  1813. X    }
  1814. X
  1815. X    /* leave last symbol unless in a pool */
  1816. X    if(sym)
  1817. X       tmp_at(-1, (levl[bhitpos.x][bhitpos.y].typ == POOL) ? -1 : 0);
  1818. X    return(0);
  1819. X}
  1820. X
  1821. Xstruct monst *
  1822. Xboomhit(dx,dy) {
  1823. X    register int i, ct;
  1824. X    register struct monst *mtmp;
  1825. X    char sym = ')';
  1826. X    extern schar xdir[], ydir[];
  1827. X
  1828. X    bhitpos.x = u.ux;
  1829. X    bhitpos.y = u.uy;
  1830. X
  1831. X    for(i=0; i<8; i++) if(xdir[i] == dx && ydir[i] == dy) break;
  1832. X    tmp_at(-1, sym);    /* open call */
  1833. X    for(ct=0; ct<10; ct++) {
  1834. X        if(i == 8) i = 0;
  1835. X        sym = ')' + '(' - sym;
  1836. X        tmp_at(-2, sym);    /* change let call */
  1837. X        dx = xdir[i];
  1838. X        dy = ydir[i];
  1839. X        bhitpos.x += dx;
  1840. X        bhitpos.y += dy;
  1841. X        if(mtmp = m_at(bhitpos.x, bhitpos.y)){
  1842. X            tmp_at(-1,-1);
  1843. X            return(mtmp);
  1844. X        }
  1845. X        if(!ZAP_POS(levl[bhitpos.x][bhitpos.y].typ)) {
  1846. X            bhitpos.x -= dx;
  1847. X            bhitpos.y -= dy;
  1848. X            break;
  1849. X        }
  1850. X        if(bhitpos.x == u.ux && bhitpos.y == u.uy) { /* ct == 9 */
  1851. X            if(rn2(20) >= 10+u.ulevel){    /* we hit ourselves */
  1852. X                (void) thitu(10, rnd(10), "boomerang");
  1853. X                break;
  1854. X            } else {    /* we catch it */
  1855. X                tmp_at(-1,-1);
  1856. X                pline("Skillfully, you catch the boomerang.");
  1857. X                return(&youmonst);
  1858. X            }
  1859. X        }
  1860. X        tmp_at(bhitpos.x, bhitpos.y);
  1861. X        if(ct % 5 != 0) i++;
  1862. X    }
  1863. X    tmp_at(-1, -1);    /* do not leave last symbol */
  1864. X    return(0);
  1865. X}
  1866. X
  1867. Xchar
  1868. Xdirlet(dx,dy) register dx,dy; {
  1869. X    return
  1870. X        (dx == dy) ? '\\' : (dx && dy) ? '/' : dx ? '-' : '|';
  1871. X}
  1872. X
  1873. X/* type == -1: monster spitting fire at you */
  1874. X/* type == -1,-2,-3: bolts sent out by wizard */
  1875. X/* called with dx = dy = 0 with vertical bolts */
  1876. Xbuzz(type,sx,sy,dx,dy)
  1877. Xregister int type;
  1878. Xregister xchar sx,sy;
  1879. Xregister int dx,dy;
  1880. X{
  1881. X    int abstype = (type == 10) ? 1 : abs(type);
  1882. X    register char *fltxt = (type == -1 || type == 10) ? "blaze of fire" : fl[abstype];
  1883. X    struct rm *lev;
  1884. X    xchar range;
  1885. X    struct monst *mon;
  1886. X
  1887. X    if(u.uswallow) {
  1888. X        register int tmp;
  1889. X
  1890. X        if(type < 0) return;
  1891. X        tmp = zhit(u.ustuck, type);
  1892. X        pline("The %s rips into %s%s",
  1893. X            fltxt, monnam(u.ustuck), exclam(tmp));
  1894. X        return;
  1895. X    }
  1896. X    if(type < 0) pru();
  1897. X    range = rn1(7,7);
  1898. X    Tmp_at(-1, dirlet(dx,dy));    /* open call */
  1899. X    while(range-- > 0) {
  1900. X        sx += dx;
  1901. X        sy += dy;
  1902. X        if((lev = &levl[sx][sy])->typ) Tmp_at(sx,sy);
  1903. X        else {
  1904. X            int bounce = 0;
  1905. X            if(cansee(sx-dx,sy-dy))
  1906. X                pline("The %s bounces!", fltxt);
  1907. X            if(ZAP_POS(levl[sx][sy-dy].typ))
  1908. X                bounce = 1;
  1909. X            if(ZAP_POS(levl[sx-dx][sy].typ)) {
  1910. X                if(!bounce || rn2(2)) bounce = 2;
  1911. X            }
  1912. X            switch(bounce){
  1913. X            case 0:
  1914. X                dx = -dx;
  1915. X                dy = -dy;
  1916. X                continue;
  1917. X            case 1:
  1918. X                dy = -dy;
  1919. X                sx -= dx;
  1920. X                break;
  1921. X            case 2:
  1922. X                dx = -dx;
  1923. X                sy -= dy;
  1924. X                break;
  1925. X            }
  1926. X            Tmp_at(-2,dirlet(dx,dy));
  1927. X            continue;
  1928. X        }
  1929. X        if(lev->typ == POOL && abstype == 1 /* fire */) {
  1930. X            range -= 3;
  1931. X            lev->typ = ROOM;
  1932. X            if(cansee(sx,sy)) {
  1933. X                mnewsym(sx,sy);
  1934. X                pline("The water evaporates.");
  1935. X            } else
  1936. X                pline("You hear a hissing sound.");
  1937. X        }
  1938. X        if(o_at(sx,sy) && abstype == 1)
  1939. X            if(burn_floor_scrolls(sx,sy) && cansee(sx,sy))  {
  1940. X                mnewsym(sx,sy);
  1941. X                pline("You see a puff of smoke.");
  1942. X            }
  1943. X        if((mon = m_at(sx,sy)) &&
  1944. X           (type != -1 || mon->data->mlet != 'D')) {
  1945. X            wakeup(mon);
  1946. X            if(rnd(20) < 18 + mon->data->ac) {
  1947. X                register int tmp = zhit(mon,abstype);
  1948. X                if(mon->mhp < 1) {
  1949. X                    if(type < 0) {
  1950. X                        if(cansee(mon->mx,mon->my))
  1951. X                          pline("%s is killed by the %s!",
  1952. X                        Monnam(mon), fltxt);
  1953. X                        mondied(mon);
  1954. X                    } else
  1955. X                        killed(mon);
  1956. X                } else
  1957. X                    hit(fltxt, mon, exclam(tmp));
  1958. X                range -= 2;
  1959. X            } else
  1960. X                miss(fltxt,mon);
  1961. X        } else if(sx == u.ux && sy == u.uy) {
  1962. X            nomul(0);
  1963. X            if(rnd(20) < 18+u.uac) {
  1964. X                register int dam = 0;
  1965. X                range -= 2;
  1966. X                pline("The %s hits you!",fltxt);
  1967. X                switch(abstype) {
  1968. X                case 0:
  1969. X                case 5:    dam = d(2,6);
  1970. X                    break;
  1971. X                case 1:
  1972. X                case 6:    if(Fire_resistance)
  1973. X                        pline("You don't feel hot!");
  1974. X                    else dam = d(6,6);
  1975. X                    if(!rn2(3)) {
  1976. X                        boil_potions();
  1977. X                        burn_scrolls();
  1978. X                    }
  1979. X                    break;
  1980. X                case 2:
  1981. X                case 7:    nomul(-rnd(25)); /* sleep ray */
  1982. X                    break;
  1983. X                case 3:
  1984. X                case 8:    if(Cold_resistance)
  1985. X                        pline("You don't feel cold!");
  1986. X                    else dam = d(6,6);
  1987. X                    break;
  1988. X                case 4:
  1989. X                case 9:    u.uhp = -1;
  1990. X                    break;
  1991. X                }
  1992. X                losehp(dam,fltxt);
  1993. X            } else pline("The %s whizzes by you!",fltxt);
  1994. X            stop_occupation();
  1995. X        }
  1996. X        if(!ZAP_POS(lev->typ)) {
  1997. X            int bounce = 0, rmn;
  1998. X            if(cansee(sx,sy)) pline("The %s bounces!",fltxt);
  1999. X            range--;
  2000. X            if(!dx || !dy || !rn2(20)){
  2001. X                dx = -dx;
  2002. X                dy = -dy;
  2003. X            } else {
  2004. X              if(ZAP_POS(rmn = levl[sx][sy-dy].typ) &&
  2005. X                (IS_ROOM(rmn) || ZAP_POS(levl[sx+dx][sy-dy].typ)))
  2006. X                bounce = 1;
  2007. X              if(ZAP_POS(rmn = levl[sx-dx][sy].typ) &&
  2008. X                (IS_ROOM(rmn) || ZAP_POS(levl[sx-dx][sy+dy].typ)))
  2009. X                if(!bounce || rn2(2))
  2010. X                    bounce = 2;
  2011. X
  2012. X              switch(bounce){
  2013. X              case 0:
  2014. X                dy = -dy;
  2015. X                dx = -dx;
  2016. X                break;
  2017. X              case 1:
  2018. X                dy = -dy;
  2019. X                break;
  2020. X              case 2:
  2021. X                dx = -dx;
  2022. X                break;
  2023. X              }
  2024. X              Tmp_at(-2, dirlet(dx,dy));
  2025. X            }
  2026. X        }
  2027. X    }
  2028. X    Tmp_at(-1,-1);
  2029. X}
  2030. X
  2031. Xzhit(mon,type)            /* returns damage to mon */
  2032. Xregister struct monst *mon;
  2033. Xregister type;
  2034. X{
  2035. X    register int tmp = 0;
  2036. X
  2037. X    switch(type) {
  2038. X    case 0:            /* magic missile */
  2039. X    case 5: tmp = d(2,6);
  2040. X        break;
  2041. X    case -1:        /* Dragon blazing fire */
  2042. X    case 1:            /* fire wand*/
  2043. X    case 6:            /* fire spell */
  2044. X    case 10:        /* Polymorphed human blazing fire */
  2045. X        if(index("Dg", mon->data->mlet)) break;
  2046. X        tmp = d(6,6);
  2047. X        if(index("YF", mon->data->mlet)) tmp += 7;
  2048. X        break;
  2049. X    case 2:            /* sleep*/
  2050. X    case 7: tmp = 0;
  2051. X        if(!resist(mon, (type == 2) ? '/' : '+', 0, NOTELL))
  2052. X            mon->mfroz = 1;
  2053. X        break;
  2054. X    case 3:            /* cold */
  2055. X    case 8:
  2056. X        if(index("YFgf", mon->data->mlet)) break;
  2057. X        tmp = d(6,6);
  2058. X        if(mon->data->mlet == 'D') tmp += 7;
  2059. X        break;
  2060. X    case 4:            /* death*/
  2061. X    case 9:
  2062. X        if(index(UNDEAD, mon->data->mlet)) break;
  2063. X        tmp = mon->mhp+1;
  2064. X        break;
  2065. X    }
  2066. X    if (resist(mon, (type < 5) ? '/' : '+', 0, NOTELL)) tmp /= 2;
  2067. X    mon->mhp -= tmp;
  2068. X    return(tmp);
  2069. X}
  2070. X
  2071. X#define    CORPSE_I_TO_C(otyp)    (char) ((otyp >= DEAD_ACID_BLOB)\
  2072. X             ?  'a' + (otyp - DEAD_ACID_BLOB)\
  2073. X             :    '@' + (otyp - DEAD_HUMAN))
  2074. Xrevive(obj)
  2075. Xregister struct obj *obj;
  2076. X{
  2077. X    register struct monst *mtmp;
  2078. X    register int let;
  2079. X
  2080. X    if(obj->olet == FOOD_SYM && obj->otyp > CORPSE) {
  2081. X#ifdef KAA
  2082. X        switch (obj->otyp) {
  2083. X            case DEAD_HUMAN: { let = 'Z'; break; }
  2084. X            case DEAD_GIANT: { let = '9'; break; }
  2085. X            case DEAD_DEMON: { let = '&'; break; }
  2086. X            default: let = CORPSE_I_TO_C(obj->otyp);
  2087. X        }
  2088. X        delobj(obj);
  2089. X/* Originally there was a bug which caused the object not to be erased
  2090. X   from the screen.  This happened because first the monster got created,
  2091. X   then the corpse removed.  Although delobj() called unpobj(), the object
  2092. X   didn't get erased from the screen because the monster was sitting on top
  2093. X   of it.  Solution: place the delobj() call before the mkmon() call. */
  2094. X        mtmp = mkmon_at(let, obj->ox, obj->oy);
  2095. X        if (mtmp && obj->otyp == DEAD_HUMAN) {
  2096. X            mtmp->mhp = mtmp->mhpmax = 100;
  2097. X            mtmp->mspeed = MFAST;
  2098. X        }
  2099. X#endif
  2100. X        /* do not (yet) revive shopkeepers */
  2101. X        /* Note: this might conceivably produce two monsters
  2102. X            at the same position - strange, but harmless */
  2103. X#ifndef KAA
  2104. X        delobj(obj);
  2105. X        mtmp = mkmon_at(CORPSE_I_TO_C(obj->otyp),obj->ox,obj->oy);
  2106. X#endif
  2107. X    }
  2108. X    return(!!mtmp);        /* TRUE if some monster created */
  2109. X}
  2110. X
  2111. Xrloco(obj)
  2112. Xregister struct obj *obj;
  2113. X{
  2114. X    register tx,ty,otx,oty;
  2115. X
  2116. X    otx = obj->ox;
  2117. X    oty = obj->oy;
  2118. X    do {
  2119. X        tx = rn1(COLNO-3,2);
  2120. X        ty = rn2(ROWNO);
  2121. X    } while(!goodpos(tx,ty));
  2122. X    obj->ox = tx;
  2123. X    obj->oy = ty;
  2124. X    if(cansee(otx,oty))
  2125. X        newsym(otx,oty);
  2126. X}
  2127. X
  2128. Xfracture_rock(obj)    /* fractured by pick-axe or wand of striking */
  2129. Xregister struct obj *obj;               /* no texts here! */
  2130. X{
  2131. X    /* unpobj(obj); */
  2132. X    obj->otyp = ROCK;
  2133. X    obj->quan = 7 + rn2(60);
  2134. X    obj->owt = weight(obj);
  2135. X    obj->olet = WEAPON_SYM;
  2136. X    if(cansee(obj->ox,obj->oy))
  2137. X        prl(obj->ox,obj->oy);
  2138. X}
  2139. X
  2140. Xboil_potions()
  2141. X{
  2142. X    register struct obj *obj, *obj2;
  2143. X    register int scrquan, i;
  2144. X    
  2145. X    for(obj = invent; obj; obj = obj2) {
  2146. X        obj2 = obj->nobj;
  2147. X        if(obj->olet == POTION_SYM) {
  2148. X            scrquan = obj->quan;
  2149. X            for(i = 1; i <= scrquan; i++) 
  2150. X                if(!rn2(3)) {
  2151. X                    pline("%s %s boils and explodes!",
  2152. X                    (obj->quan != 1) ? "One of your" : "Your",
  2153. X                    xname(obj));
  2154. X                    potionbreathe(obj);
  2155. X                    useup(obj);
  2156. X                    losehp(rn2(4),"boiling potion");
  2157. X                }
  2158. X        }
  2159. X    }
  2160. X}
  2161. X                
  2162. Xburn_scrolls()
  2163. X{
  2164. X    register struct obj *obj, *obj2;
  2165. X    register int cnt = 0;
  2166. X    register int scrquan, i;
  2167. X
  2168. X    for(obj = invent; obj; obj = obj2) {
  2169. X        obj2 = obj->nobj;
  2170. X        if(obj->olet == SCROLL_SYM) {
  2171. X            scrquan = obj->quan;
  2172. X            for(i = 1; i <= scrquan ; i++)
  2173. X                if(!rn2(3))  {
  2174. X                    cnt++;
  2175. X                    useup(obj);
  2176. X                }
  2177. X        }
  2178. X    }
  2179. X
  2180. X    /* "Killed by a burning scrolls" doesn't make too much sense.  KAA*/
  2181. X    if (cnt) {
  2182. X        pline("%s of your scrolls catch%s fire!",
  2183. X        cnt==1 ? "One" : "Some", cnt==1 ? "es" : "");
  2184. X        if(Fire_resistance)
  2185. X            pline("You aren't hurt!");
  2186. X        else
  2187. X            losehp(cnt,"burning scroll");
  2188. X    }
  2189. X}
  2190. X
  2191. Xresist(mtmp, olet, damage, tell)
  2192. Xregister struct monst    *mtmp;
  2193. Xregister char    olet;
  2194. Xregister int    damage, tell;
  2195. X{
  2196. Xregister int    resisted = 0;
  2197. X#ifdef HARD
  2198. Xregister int    level;
  2199. X
  2200. X    switch(olet)  {
  2201. X
  2202. X        case '/':    level = 8;
  2203. X            break;
  2204. X
  2205. X        case '?':    level = 6;
  2206. X            break;
  2207. X
  2208. X        case '!':    level = 5;
  2209. X            break;
  2210. X
  2211. X        default:    level = u.ulevel;
  2212. X            break;
  2213. X    }
  2214. X
  2215. X    resisted = (rn2(100) - mtmp->data->mlevel + level) < mtmp->data->mr;
  2216. X    if(resisted) {
  2217. X
  2218. X        if(tell) pline("The %s resists!", mtmp->data->mname);
  2219. X        mtmp->mhp -= damage/2;
  2220. X    } else
  2221. X#endif
  2222. X        mtmp->mhp -= damage;
  2223. X
  2224. X    if(mtmp->mhp < 1) killed(mtmp);
  2225. X    return(resisted);
  2226. X}
  2227. X
  2228. X/*
  2229. X * burn scrolls on floor at position x,y
  2230. X * return the number of scrolls burned
  2231. X */
  2232. Xint
  2233. Xburn_floor_scrolls(x,y)
  2234. X{
  2235. X    register struct obj *obj, *obj2;
  2236. X    register int scrquan, i;
  2237. X    register int cnt = 0;
  2238. X
  2239. X    for(obj = fobj; obj; obj = obj2) {
  2240. X        obj2 = obj->nobj;
  2241. X        /* Bug fix - KAA */
  2242. X        if(obj->ox == x && obj->oy == y && obj->olet == SCROLL_SYM) {
  2243. X            scrquan = obj->quan;
  2244. X            for(i = 1; i <= scrquan ; i++)
  2245. X                if(!rn2(3))  {
  2246. X                    cnt++;
  2247. X                    useupf(obj);
  2248. X                }
  2249. X        }
  2250. X    }
  2251. X    return(cnt);
  2252. X}
  2253. X
  2254. Xmakewish()    /* Separated as there are now 3 places you can wish at. */
  2255. X{
  2256. X    char buf[BUFSZ];
  2257. X    register struct obj *otmp;
  2258. X    extern struct obj *readobjnam(), *addinv();
  2259. X    int wishquan, mergquan;
  2260. X
  2261. X    pline("You may wish for an object. What do you want? ");
  2262. X    getlin(buf);
  2263. X    if(buf[0] == '\033') buf[0] = 0;
  2264. X    otmp = readobjnam(buf);
  2265. X#ifdef KAA
  2266. X/* Wishing for gold has been implemented in readobjnam() and returns 0
  2267. X   if successful. */
  2268. X    if (otmp) { 
  2269. X#endif
  2270. X        wishquan = otmp->quan;
  2271. X        otmp = addinv(otmp);
  2272. X        /* indented lines added below so quantity shows
  2273. X         *  right.     GAN - 11/13/86
  2274. X         */
  2275. X          mergquan = otmp->quan;
  2276. X          otmp->quan = wishquan; /* to fool prinv() */
  2277. X        prinv(otmp);
  2278. X          otmp->quan = mergquan;
  2279. X#ifdef KAA
  2280. X    }
  2281. X#endif
  2282. X}
  2283. END_OF_zap.c
  2284. if test 23766 -ne `wc -c <zap.c`; then
  2285.     echo shar: \"zap.c\" unpacked with wrong size!
  2286. fi
  2287. # end of overwriting check
  2288. fi
  2289. echo shar: End of archive 3 \(of 16\).
  2290. cp /dev/null ark3isdone
  2291. MISSING=""
  2292. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ; do
  2293.     if test ! -f ark${I}isdone ; then
  2294.     MISSING="${MISSING} ${I}"
  2295.     fi
  2296. done
  2297. if test "${MISSING}" = "" ; then
  2298.     echo You have unpacked all 16 archives.
  2299.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2300. else
  2301.     echo You still need to unpack the following archives:
  2302.     echo "        " ${MISSING}
  2303. fi
  2304. ##  End of shell archive.
  2305. exit 0
  2306.